`timescale 1 ns / 1 ps
/*------------------- include --------------------*/
`ifndef __SIM__
`define __INCLUDE__
`endif 


`ifdef __INCLUDE__ 
`include "serving/serving.v"
`include "wb_gpio.v"
`include "wb_tik.v"
`include "wb_spi.v"
`include "wb_iic.v"
`include "wb_mux_4.v"
`endif 
/*-----------------------------------------------*/

`ifndef SYS_FREQ
`define SYS_FREQ 12_000_000  // 系统时钟频率
`endif 
module top(
    input wire clk , 
    output  led ,
    output reg txd ,
    
    output wire  spi0_cs ,
    output wire  spi0_sck ,
    output wire  spi0_mosi ,
    input  wire spi0_miso ,
    
    // i2c0 引脚
    output wire    i2c0_scl ,
    inout  wire    i2c0_sda 
); 

/*---------------------------- mcu nets --------------------------*/

reg  rst_n ;
reg [12:0] rst_cnt = 0  ;

reg [31:0]tik ;




// 产生复位信号
always @(posedge clk ) begin
    {rst_cnt , rst_n } <= { {&rst_cnt ? rst_cnt : rst_cnt + 1'b1}  ,  {&rst_cnt} } ;
end

//------------------------------------------------  Wishbone 连接线 -------------------------------------------------------
                 
// Wishbone slave 0 wire 
wire [31:0]   wbs0_adr ;         // ADR_O() address output
wire [31:0]   wbs0_rdt ;         // DAT_I() data in
wire [31:0]   wbs0_dat ;         // DAT_O() data out
wire          wbs0_we ;          // WE_O write enable output
wire [3 :0]   wbs0_sel ;         // SEL_O() select output
wire          wbs0_stb ;         // STB_O strobe output
wire          wbs0_ack ;         // ACK_I acknowledge input
wire [31:0]   wbs0_addr ;        // Slave address prefix
wire [31:0]   wbs0_addr_msk ;    // Slave address prefix mask
                 
// Wishbone slave 1 wire 
wire [31:0]   wbs1_adr ;         // ADR_O() address output
wire [31:0]   wbs1_rdt ;         // DAT_I() data in
wire [31:0]   wbs1_dat ;         // DAT_O() data out
wire          wbs1_we ;          // WE_O write enable output
wire [3 :0]   wbs1_sel ;         // SEL_O() select output
wire          wbs1_stb ;         // STB_O strobe output
wire          wbs1_ack ;         // ACK_I acknowledge input
wire [31:0]   wbs1_addr ;        // Slave address prefix
wire [31:0]   wbs1_addr_msk ;    // Slave address prefix mask
                 
// Wishbone slave 2 wire 
wire [31:0]   wbs2_adr ;         // ADR_O() address output
wire [31:0]   wbs2_rdt ;         // DAT_I() data in
wire [31:0]   wbs2_dat ;         // DAT_O() data out
wire          wbs2_we ;          // WE_O write enable output
wire [3 :0]   wbs2_sel ;         // SEL_O() select output
wire          wbs2_stb ;         // STB_O strobe output
wire          wbs2_ack ;         // ACK_I acknowledge input
wire [31:0]   wbs2_addr ;        // Slave address prefix
wire [31:0]   wbs2_addr_msk ;    // Slave address prefix mask
                 
// Wishbone slave 3 wire 
wire [31:0]   wbs3_adr ;         // ADR_O() address output
wire [31:0]   wbs3_rdt ;         // DAT_I() data in
wire [31:0]   wbs3_dat ;         // DAT_O() data out
wire          wbs3_we ;          // WE_O write enable output
wire [3 :0]   wbs3_sel ;         // SEL_O() select output
wire          wbs3_stb ;         // STB_O strobe output
wire          wbs3_ack ;         // ACK_I acknowledge input
wire [31:0]   wbs3_addr ;        // Slave address prefix
wire [31:0]   wbs3_addr_msk ;    // Slave address prefix mask   

//------------------------------------------------  Wishbone 地址分配 -------------------------------------------------------
assign {wbs0_addr , wbs0_addr_msk } = {32'h8000_0000 , 32'hffff_0000} ; // GPIO
assign {wbs1_addr , wbs1_addr_msk } = {32'h8001_0000 , 32'hffff_0000} ; // TIK
assign {wbs2_addr , wbs2_addr_msk } = {32'h8002_0000 , 32'hffff_0000} ; // SPI 
assign {wbs3_addr , wbs3_addr_msk } = {32'h8003_0000 , 32'hffff_0000} ; // IIC 


/*----------------------------- 模块 ------------------------------*/
wire [31:0]wb_adr;
wire [31:0]wb_dat;
wire [3:0] wb_sel;
wire wb_we ;
wire wb_stb;
wire  [31:0]wb_rdt;
wire  wb_ack;

wire rst ; 
assign rst = ~rst_n ;

serving #(
    .memfile ("firmware.hex"),
    .memsize (8192) ,// bytes 
    .RESET_STRATEGY("MINI")
)mcu
(
    .i_clk(clk),
    .i_rst(~rst_n),
    // .i_timer_irq(timer_src),

    .o_wb_adr(wb_adr), // output wire [31:0] 
    .o_wb_dat(wb_dat), // output wire [31:0] 
    .o_wb_sel(wb_sel), // output wire [3:0]  
    .o_wb_we (wb_we ), // output wire 	      
    .o_wb_stb(wb_stb), // output wire 	      
    .i_wb_rdt(wb_rdt), // input wire [31:0]  
    .i_wb_ack(wb_ack)  // input wire 	      
);

wb_mux_4 #(
    .DATA_WIDTH(32) , 
    .ADDR_WIDTH(32)            
) u_wb_mux (
    .clk( clk) , 
    .rst( ~rst_n) ,
    .wbm_adr_i( wb_adr),
    .wbm_dat_i( wb_dat),
    .wbm_dat_o( wb_rdt),
    .wbm_we_i( wb_we),    
    .wbm_sel_i( wb_sel),
    .wbm_stb_i( wb_stb),
    .wbm_ack_o( wb_ack),
                 
   //Wishbone slave 0 output
    .wbs0_adr_o( wbs0_adr),    // ADR_O() address output
    .wbs0_dat_i( wbs0_rdt),    // DAT_I() data in
    .wbs0_dat_o( wbs0_dat),    // DAT_O() data out
    .wbs0_we_o ( wbs0_we),     // WE_O write enable output
    .wbs0_sel_o( wbs0_sel),    // SEL_O() select output
    .wbs0_stb_o( wbs0_stb),    // STB_O strobe output
    .wbs0_ack_i( wbs0_ack),    // ACK_I acknowledge input

    //Wishbone slave 0 address configuration
    .wbs0_addr    ( wbs0_addr), // Slave address prefix
    .wbs0_addr_msk( wbs0_addr_msk), // Slave address prefix mask
                 
    //Wishbone slave 1 output
    .wbs1_adr_o( wbs1_adr),    // ADR_O() address output
    .wbs1_dat_i( wbs1_rdt),    // DAT_I() data in
    .wbs1_dat_o( wbs1_dat),    // DAT_O() data out
    .wbs1_we_o ( wbs1_we),     // WE_O write enable output
    .wbs1_sel_o( wbs1_sel),    // SEL_O() select output
    .wbs1_stb_o( wbs1_stb),    // STB_O strobe output
    .wbs1_ack_i( wbs1_ack),    // ACK_I acknowledge input

    //Wishbone slave 1 address configuration
    .wbs1_addr    ( wbs1_addr), // Slave address prefix
    .wbs1_addr_msk( wbs1_addr_msk), // Slave address prefix mask
                 
    //Wishbone slave 2 output
    .wbs2_adr_o( wbs2_adr),    // ADR_O() address output
    .wbs2_dat_i( wbs2_rdt),    // DAT_I() data in
    .wbs2_dat_o( wbs2_dat),    // DAT_O() data out
    .wbs2_we_o ( wbs2_we),     // WE_O write enable output
    .wbs2_sel_o( wbs2_sel),    // SEL_O() select output
    .wbs2_stb_o( wbs2_stb),    // STB_O strobe output
    .wbs2_ack_i( wbs2_ack),    // ACK_I acknowledge input

    //Wishbone slave 2 address configuration
    .wbs2_addr    ( wbs2_addr), // Slave address prefix
    .wbs2_addr_msk( wbs2_addr_msk), // Slave address prefix mask
                 
    //Wishbone slave 3 output
    .wbs3_adr_o( wbs3_adr),    // ADR_O() address output
    .wbs3_dat_i( wbs3_rdt),    // DAT_I() data in
    .wbs3_dat_o( wbs3_dat),    // DAT_O() data out
    .wbs3_we_o ( wbs3_we),     // WE_O write enable output
    .wbs3_sel_o( wbs3_sel),    // SEL_O() select output
    .wbs3_stb_o( wbs3_stb),    // STB_O strobe output
    .wbs3_ack_i( wbs3_ack),    // ACK_I acknowledge input

    //Wishbone slave 3 address configuration
    .wbs3_addr    ( wbs3_addr), // Slave address prefix
    .wbs3_addr_msk( wbs3_addr_msk)  // Slave address prefix mask
)  ;


wb_gpio #
(
    .DATA_WIDTH(32),                  // width of data bus in bits (8, 16, 32, or 64)
    .ADDR_WIDTH(32)                  // width of address bus in bits
) u_wb_gpio (
    .clk( clk),
    .rst( rst),

    .wbm_adr_i( wbs0_adr ),    // ADR_I() address
    .wbm_dat_i( wbs0_dat ),    // DAT_I() data in
    .wbm_dat_o( wbs0_rdt ),    // DAT_O() data out
    .wbm_we_i ( wbs0_we  ),    // WE_I write enable input
    .wbm_sel_i( wbs0_sel ),    // SEL_I() select input
    .wbm_stb_i( wbs0_stb ),    // STB_I strobe input
    .wbm_ack_o( wbs0_ack ),     // ACK_O acknowledge output

    .gpio0( led )
);


wb_tik #
(
    .DATA_WIDTH(32),                  // width of data bus in bits (8, 16, 32, or 64)
    .ADDR_WIDTH(32),                  // width of address bus in bits
    .SYS_FREQ(`SYS_FREQ)             // sys freq Hz
) u_wb_tik (
    .clk( clk),
    .rst( rst),

    .wbm_adr_i( wbs1_adr ),    // ADR_I() address
    .wbm_dat_i( wbs1_dat ),    // DAT_I() data in
    .wbm_dat_o( wbs1_rdt ),    // DAT_O() data out
    .wbm_we_i ( wbs1_we  ),    // WE_I write enable input
    .wbm_sel_i( wbs1_sel ),    // SEL_I() select input
    .wbm_stb_i( wbs1_stb ),    // STB_I strobe input
    .wbm_ack_o( wbs1_ack )     // ACK_O acknowledge output
);

wb_spi #
(
    .DATA_WIDTH(32),                  // width of data bus in bits (8, 16, 32, or 64)
    .ADDR_WIDTH(32)                  // width of address bus in bits
) u_wb_spi (
    .clk( clk),
    .rst( rst),

    .wbm_adr_i( wbs2_adr ),    // ADR_I() address
    .wbm_dat_i( wbs2_dat ),    // DAT_I() data in
    .wbm_dat_o( wbs2_rdt ),    // DAT_O() data out
    .wbm_we_i ( wbs2_we  ),    // WE_I write enable input
    .wbm_sel_i( wbs2_sel ),    // SEL_I() select input
    .wbm_stb_i( wbs2_stb ),    // STB_I strobe input
    .wbm_ack_o( wbs2_ack ),    // ACK_O acknowledge output

    .spi0_cs   ( spi0_cs   ),
    .spi0_sck  ( spi0_sck  ),
    .spi0_mosi ( spi0_mosi ),
    .spi0_miso ( spi0_miso )
);


wb_iic #
(
    .DATA_WIDTH(32),                  // width of data bus in bits (8, 16, 32, or 64)
    .ADDR_WIDTH(32)                  // width of address bus in bits
) u_wb_iic (
    .clk( clk),
    .rst( rst),

    .wbm_adr_i( wbs3_adr),    // ADR_I() address
    .wbm_dat_i( wbs3_dat),    // DAT_I() data in
    .wbm_dat_o( wbs3_rdt),    // DAT_O() data out
    .wbm_we_i ( wbs3_we ),    // WE_I write enable input
    .wbm_sel_i( wbs3_sel),    // SEL_I() select input
    .wbm_stb_i( wbs3_stb),    // STB_I strobe input
    .wbm_ack_o( wbs3_ack),     // ACK_O acknowledge output

    .scl0  ( i2c0_scl ),
    .sda0  ( i2c0_sda )
);




endmodule
